Restyle the embed
Make the map look like part of your application. Switch between the basemaps the author published, turn the map's own controls on and off, read the legend as data and draw it your way, and export a picture of the map as the reader sees it.
What to notice
setChromecan hide a control the author configured; it cannot add one they did not.setBasemaptakes an id fromgetBasemaps()- there is no way to load a style of your own.exportImageandprintare refused when a sensitivity label on the map's data does not allow export.fullscreen()runs on your page and needs a click there.
The code
The complete page. Swap in your own publish id, and ask the map's author to add your site to its allowed origins.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Restyle the embed - Icon Map Embed API</title>
<link rel="stylesheet" href="https://www.icon-map.com/embed-examples/examples.css"> <!-- demo styling only -->
</head>
<body>
<div class="ex-main">
<div class="ex-side">
<h2>Basemap</h2>
<div class="ex-chips" id="basemaps"></div>
<h2>The map's own controls</h2>
<label class="ex-check"><input type="checkbox" data-chrome="legend"> Legend</label>
<label class="ex-check"><input type="checkbox" data-chrome="layerControl"> Layer control</label>
<label class="ex-check"><input type="checkbox" data-chrome="bookmarksBar"> Bookmarks bar</label>
<label class="ex-check"><input type="checkbox" data-chrome="clickPopups" checked> Click popups</label>
<h2>Cards</h2>
<label class="ex-check"><input type="checkbox" id="cards"> Chart and slicers</label>
<h2>A legend drawn by this page</h2>
<div id="legend"></div>
<h2>Export</h2>
<div class="ex-chips">
<button id="png">Download PNG</button>
<button id="full">Full screen</button>
</div>
</div>
<div id="map"></div>
</div>
<script src="https://www.icon-map.com/js/iconmap-embed/2/iconmap-embed.umd.min.js"></script>
<script>
const el = document.getElementById("map");
const map = IconMapEmbed.embed(el, {
publishId: "pub_...",
// The map is a globe: let this page's own background show in the space around it.
background: "transparent",
// Start bare: the map's panels off, its cards hidden.
chrome: { legend: false, layerControl: false, bookmarksBar: false, tourTransport: false },
visibility: { visuals: { "chart-continent": false, "slicer-continent": false, "slicer-size": false, "slicer-capital": false } },
events: ["basemapChanged"],
});
map.ready.catch((error) => console.error(error.code, error.message));
// --- basemaps: only the ones the author published with the map ---------------------
map.getBasemaps().then((basemaps) => {
for (const basemap of basemaps) {
const button = Object.assign(document.createElement("button"), { textContent: basemap.name });
button.dataset.basemap = basemap.id;
button.classList.toggle("on", basemap.active);
button.onclick = () => map.setBasemap({ basemapId: basemap.id });
document.getElementById("basemaps").append(button);
}
});
map.on("basemapChanged", ({ basemapId }) => {
for (const b of document.querySelectorAll("[data-basemap]")) b.classList.toggle("on", b.dataset.basemap === basemapId);
});
// --- chrome: hide or show controls the author configured (it cannot add new ones) ----
for (const box of document.querySelectorAll("[data-chrome]")) {
box.onchange = () => map.setChrome({ [box.dataset.chrome]: box.checked });
}
// Charts and slicers are visuals, toggled like layers.
document.getElementById("cards").onchange = (e) => {
const visuals = {};
for (const id of ["chart-continent","slicer-continent","slicer-size","slicer-capital"]) visuals[id] = e.target.checked;
map.setVisibility({ visuals });
};
// --- the legend as DATA: draw it your way, anywhere on your page --------------------
map.getLegend().then((entries) => {
const host = document.getElementById("legend");
for (const entry of entries) {
host.append(Object.assign(document.createElement("div"), { textContent: entry.title, style: "margin:6px 0 3px;font-weight:600" }));
for (const section of entry.sections) {
for (const item of section.items) {
if (item.kind === "gradient" && item.stops) {
// A colour ramp arrives as its stops: one CSS gradient draws it.
const ramp = Object.assign(document.createElement("div"), { className: "ex-ramp" });
ramp.style.background = `linear-gradient(90deg, ${item.stops.map((s) => `${s.color} ${s.position * 100}%`).join(", ")})`;
host.append(ramp);
} else if (item.color && item.label) {
const row = document.createElement("div");
const swatch = Object.assign(document.createElement("span"), { className: "ex-swatch" });
swatch.style.background = item.color;
row.append(swatch, item.label);
host.append(row);
}
}
}
}
});
// --- a picture of the map as the reader sees it -------------------------------------
document.getElementById("png").onclick = async () => {
const image = await map.exportImage({ width: 1600 });
Object.assign(document.createElement("a"), { href: image.dataUrl, download: "world-cities.png" }).click();
};
// Full screen runs on YOUR page, so it needs a click here - which this is.
document.getElementById("full").onclick = () => map.fullscreen();
</script>
</body>
</html>